package com.laicunba.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.stereotype.Service;

import com.laicunba.pojo.FinancingTargetBidDO;
import com.laicunba.pojo.FinancingTargetDO;
import com.laicunba.pojo.RateIncrCouponDO;
import com.laicunba.pojo.UserDO;
import com.laicunba.service.RateIncrCouponService;
import com.laicunba.util.AssertUtil;
import com.laicunba.util.StringUtil;

@Service
public class RateIncrCouponServiceImpl extends BaseServiceImpl implements RateIncrCouponService {
	private static final Logger LOG = Logger.getLogger(RateIncrCouponServiceImpl.class);

	@Override
	public List<RateIncrCouponDO> findUseableCoupon(String uid) {
		return queryDao.selectList("RATE_INCR_COUPON.findUseableCoupon", uid);
	}

	@Override
	public boolean testForConditions(FinancingTargetBidDO bidDO, RateIncrCouponDO rateIncrCouponDO, FinancingTargetDO financingTargetDO) {
		AssertUtil.assertNotNull(rateIncrCouponDO, "RATE_INCR_COUPON_NOT_EXIST");
		AssertUtil.assertTrue(StringUtil.isEmpty(rateIncrCouponDO.getFinancingTargetBidId()), "RATE_INCR_COUPON_BID_ID_EXIST");
		// 是否已用?
		AssertUtil.assertTrue("new".equalsIgnoreCase(rateIncrCouponDO.getStatus()), "RATE_INCR_COUPON_IS_USED");
		// 是否该用户拥有?
		AssertUtil.assertTrue(bidDO.getBidUserId().equals(rateIncrCouponDO.getUserId()), "RATE_INCR_COUPON_USERID_ERROR");
		AssertUtil.assertNotNull(rateIncrCouponDO.getBeginTime(), "RATE_INCR_COUPON_HAS_NO_BEGIN_TIME");
		AssertUtil.assertNotNull(rateIncrCouponDO.getEndTime(), "RATE_INCR_COUPON_HAS_NO_END_TIME");
		AssertUtil.assertTrue(rateIncrCouponDO.getRate() != null && rateIncrCouponDO.getRate().compareTo(BigDecimal.ZERO) >= 0, "RATE_INCR_COUPON_RATE_TOO_SMALL");
		// 是否过有效期?
		Date now = new Date();
		AssertUtil.assertTrue(rateIncrCouponDO.getBeginTime().before(now) && rateIncrCouponDO.getEndTime().after(now), "RATE_INCR_COUPON_VALID_ERROR");

		// 加息标，不能使用
		AssertUtil.assertTrue(financingTargetDO.getIncrRate() == null || financingTargetDO.getIncrRate().compareTo(BigDecimal.ZERO) == 0, "CANT_USE_RATE_COUPON");
		AssertUtil.assertTrue(!financingTargetDO.getName().contains("加息"), "CANT_USE_RATE_COUPON");
		// 检查使用条件
		if (StringUtil.isEmpty(rateIncrCouponDO.getConditions())) {
			return true;
		}

		// [{"period":30,"buy_amount":1000}]
		try {
			String errorCode = "";
			JSONArray conditions = (JSONArray) new JSONParser().parse(rateIncrCouponDO.getConditions());
			for (int i = 0; i < conditions.size(); i++) {
				JSONObject condition = (JSONObject) conditions.get(i);
				errorCode = "";
				// 满N元?
				if (condition.containsKey("buy_amount")) {
					if (bidDO.getBuyAmount().compareTo(new BigDecimal(condition.get("buy_amount").toString())) < 0) {
						errorCode = "RATE_INCR_BUY_AMOUNT_CONDITION_ERROR";
					}
				}
				// 满N天?
				if (condition.containsKey("period")) {
					if (financingTargetDO.getPeriod() < Integer.parseInt(condition.get("period").toString())) {
						errorCode = "RATE_INCR_PERIOD_CONDITION_ERROR";
					}
				}
				// 定标还是活标?
				if (condition.containsKey("target_type")) {
					if (!bidDO.getType().equalsIgnoreCase(condition.get("target_type").toString())) {
						errorCode = "RATE_INCR_TARGET_TYPE_CONDITION_ERROR";
					}
				}

				if (StringUtil.isEmpty(errorCode)) {
					return true;
				}

			}

			if (StringUtil.isNotEmpty(errorCode)) {
				AssertUtil.assertFail(errorCode);
			}

		} catch (ParseException e) {
			LOG.error("现金券条件解释出错:" + rateIncrCouponDO.getConditions(), e);
			return false;
		}
		return false;
	}

	@Override
	public List<RateIncrCouponDO> find(String uid) {
		return queryDao.selectList("RATE_INCR_COUPON.find", uid);
	}

	@Override
	public boolean testForConditions(RateIncrCouponDO rateIncrCouponDO, UserDO buyer, FinancingTargetDO financingTargetDO, BigDecimal buyAmt) {

		return testForConditions(buyer.getId(), rateIncrCouponDO, financingTargetDO, buyAmt);
	}

	private boolean testForConditions(String uid, RateIncrCouponDO rateIncrCouponDO, FinancingTargetDO financingTargetDO, BigDecimal buyAmt) {
		AssertUtil.assertNotNull(rateIncrCouponDO, "RATE_INCR_COUPON_NOT_EXIST");
		AssertUtil.assertTrue(StringUtil.isEmpty(rateIncrCouponDO.getFinancingTargetBidId()), "RATE_INCR_COUPON_BID_ID_EXIST");
		// 是否已用?
		AssertUtil.assertTrue("new".equalsIgnoreCase(rateIncrCouponDO.getStatus()), "RATE_INCR_COUPON_IS_USED");
		// 是否该用户拥有?
		AssertUtil.assertTrue(uid.equals(rateIncrCouponDO.getUserId()), "RATE_INCR_COUPON_USERID_ERROR");
		AssertUtil.assertNotNull(rateIncrCouponDO.getBeginTime(), "RATE_INCR_COUPON_HAS_NO_BEGIN_TIME");
		AssertUtil.assertNotNull(rateIncrCouponDO.getEndTime(), "RATE_INCR_COUPON_HAS_NO_END_TIME");
		AssertUtil.assertTrue(rateIncrCouponDO.getRate() != null && rateIncrCouponDO.getRate().compareTo(BigDecimal.ZERO) >= 0, "RATE_INCR_COUPON_RATE_TOO_SMALL");
		// 是否过有效期?
		Date now = new Date();
		AssertUtil.assertTrue(rateIncrCouponDO.getBeginTime().before(now) && rateIncrCouponDO.getEndTime().after(now), "RATE_INCR_COUPON_VALID_ERROR");

		// 加息标，不能使用
		AssertUtil.assertTrue(financingTargetDO.getIncrRate() == null || financingTargetDO.getIncrRate().compareTo(BigDecimal.ZERO) == 0, "CANT_USE_RATE_COUPON");
		AssertUtil.assertTrue(!financingTargetDO.getName().contains("加息"), "CANT_USE_RATE_COUPON");
		// 检查使用条件
		if (StringUtil.isEmpty(rateIncrCouponDO.getConditions())) {
			return true;
		}

		// [{"period":30,"buy_amount":1000}]
		try {
			String errorCode = "";
			JSONArray conditions = (JSONArray) new JSONParser().parse(rateIncrCouponDO.getConditions());
			for (int i = 0; i < conditions.size(); i++) {
				JSONObject condition = (JSONObject) conditions.get(i);
				errorCode = "";
				// 满N元?
				if (condition.containsKey("buy_amount")) {
					if (buyAmt.compareTo(new BigDecimal(condition.get("buy_amount").toString())) < 0) {
						errorCode = "RATE_INCR_BUY_AMOUNT_CONDITION_ERROR";
					}
				}
				// 满N天?
				if (condition.containsKey("period")) {
					if (financingTargetDO.getPeriod() < Integer.parseInt(condition.get("period").toString())) {
						errorCode = "RATE_INCR_PERIOD_CONDITION_ERROR";
					}
				}
				// 定标还是活标?
				if (condition.containsKey("target_type")) {
					if (!financingTargetDO.getType().equalsIgnoreCase(condition.get("target_type").toString())) {
						errorCode = "RATE_INCR_TARGET_TYPE_CONDITION_ERROR";
					}
				}

				if (StringUtil.isEmpty(errorCode)) {
					return true;
				}

			}

			if (StringUtil.isNotEmpty(errorCode)) {
				AssertUtil.assertFail(errorCode);
			}

		} catch (ParseException e) {
			LOG.error("现金券条件解释出错:" + rateIncrCouponDO.getConditions(), e);
			return false;
		}
		return false;
	}

}
